/*!
 * \file iegenlib_context.cc
 *
 * \date Started: 12/20/10
 * \date Last Modified: 12/20/10
 * \authors Alan LaMielle
 */

#include <iegenlib/iegenlib.h>

namespace iegenlib{

IEGenLibContext::IEGenLibContext(bool simplifyConjunctions):
   simplifyConjunctions(simplifyConjunctions){
}

bool IEGenLibContext::operator==(IEGenLibContext const& other) const{
  bool res;

  res=this->getSimplifyConjunctions()==other.getSimplifyConjunctions();
  res=res && this->getSymbolics()==other.getSymbolics();
  res=res && this->getInversePairs()==other.getInversePairs();

  return res;
}

set<string> IEGenLibContext::getSymbolicNames() const{
  set<string> sym_names;
  set<Symbolic> symbolics;

  symbolics=this->getSymbolics();

  for(set<Symbolic>::const_iterator sym_itr=symbolics.begin();
      sym_itr!=symbolics.end(); ++sym_itr){
    sym_names.insert(sym_itr->getName());
  }

  return sym_names;
}

void IEGenLibContext::addInversePair(string name1,string name2){
  string inverse_name;

  if(""==name1 || ""==name2){
    throw StringException("Cannot add empty function names as inverses");
  }
  else if(name1==name2){
    throw StringException("Cannot add a function as an inverse of itself");
  }
  else if(this->hasInverse(name1,inverse_name)){
    throw StringException("Function name "+name1+" already has an inverse");
  }
  else if(this->hasInverse(name2,inverse_name)){
    throw StringException("Function name "+name2+" already has an inverse");
  }

  this->inverse_pairs1[name1]=name2;
  this->inverse_pairs2[name2]=name1;
}

set<pair<string,string> > IEGenLibContext::getInversePairs() const{
  set<pair<string,string> > pairs;

  for(map<string,string>::const_iterator kv=this->inverse_pairs1.begin();
      kv!=this->inverse_pairs1.end(); ++kv){
    pairs.insert(make_pair(kv->first,kv->second));
  }

  return pairs;
}

bool IEGenLibContext::hasInverse(string name,string &inverse) const{
  bool res;
  map<string,string>::const_iterator inverse_name;

  res=false;

  inverse_name=this->inverse_pairs1.find(name);
  if(inverse_name!=this->inverse_pairs1.end()){
    inverse=inverse_name->second;
    res=true;
  }

  if(!res){
    inverse_name=this->inverse_pairs2.find(name);
    if(inverse_name!=this->inverse_pairs2.end()){
      inverse=inverse_name->second;
      res=true;
    }
  }

  return res;
}

}//end namespace iegenlib
